<!DOCTYPE html>
<html lang="zh">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    

<script>
// this是一个指针型变量
// this指向不是固定的，会随着执行环境的改变而改变
// 学习this的两个目标：1.能判断this的指向；2.会修改this的指向。

// 判断this的指向：
// 1.在全局中，this指向window对象
// 2.在函数中，this指向调用函数的对象
// 3.在事件处理函数中，this指向添加事件的DOM元素
// 4.在构造函数或原型对象的方法中，this通常指向实例对象
// 5.函数找不到调用对象时，this指向window对象

// 修改this的指向：
// bind(obj,参数...)修改函数内部的this指向，并返回改变this指向之后的函数
// call(obj,参数...)修改函数内部的this指向，并指向该函数，返回值取决于当前函数的返回值
// apply(obj,[参数...])修改函数内部的this指向，并指向该函数，返回值取决于当前函数的返回值

// prototype原型（显式原型）
// 每一个函数对象都有prototype属性
// prototype属性的值是一个对象即原型对象
// prototype的作用：实现继承

// __proto__原型（隐式原型）
// 每一个对象都有__proto__属性
// __proto__属性指向创建该对象的构造函数的prototype属性
// __proto__的作用：维护原型链

// 原型链：从对象的__proto__属性开始，连接的所有对象即原型链

// JS引擎查找对象属性的顺序：1.先查找对象自身；2.查找对象的__proto__属性；3.一直查找到null

// obj.hasOwnProperty(attr)查找obj自身是否有attr属性，返回布尔值
// instanceof运算符，用于检测对象的某个构造函数的prototype是否在对象的正原型链中
// arr instanceof Array 判断在arr的整个原型链中是否有Array.prototype

// 作者制定的四条线：
// 1. Function.__proto__ === Function.prototype
// 2. Object.__proto__ === Function.prototype
// 3. Object.prototype.__proto__ === null
// 4. Function.prototype.__proto__ === Object.prototype

// new运算符做了什么？
// 1.创建一个空对象
// var cat1 = new Object();
// 2.将cat1的__proto__属性指向构造函数的原型
// cat1.__proto__ = Cat.prototype
// 3.修改构造函数内部的this指向cat1，并执行构造函数
// Cat.call(cat1)
// 4.new调用的返回值
//     1.如果返回基本类型，会被忽略掉，默认返回this
//     2.如果返回引用类型，不会返回默认的this

// 继承：一个对象没有实现某些属性方法，可以去拿别人的属性方法来使用
// 1.构造函数继承（对象冒充继承）
// 2.原型继承
// 3.组合继承（混合继承）

</script>
</body>
</html>